#include <gfx/dx12/render_target.h>
#include <gfx/dx12/core.h>
#include <gfx/dx12/helper.h>
#include <gfx/dx12/command.h>

primal::gfx::RenderTarget::RenderTarget() :ComPtr<ID3D12Resource>{}, view_port{}, scissor{}, clear_value{}
{
	srv().allocator(this->shader_view);
	rtv().allocator(this->render_view);
}

primal::gfx::RenderTarget::RenderTarget(u32 width, u32 height) :ComPtr<ID3D12Resource>{}, view_port{}, scissor{}, clear_value{}
{
	clear_value.Color[0] = 0.5f;
	clear_value.Color[1] = 1.0f;
	srv().allocator(this->shader_view);
	rtv().allocator(this->render_view);
	this->resize(width, height);
}

primal::gfx::RenderTarget::~RenderTarget()
{
	srv().free(this->shader_view);
	rtv().free(this->render_view);
}

void primal::gfx::RenderTarget::resize(u32 width, u32 height)
{
	this->view_port.Width = static_cast<float>(width);
	this->view_port.Height = static_cast<float>(height);
	this->view_port.MaxDepth = 1.0f;
	this->scissor.right = static_cast<long>(width);
	this->scissor.bottom = static_cast<long>(height);
	this->Reset();
	d3dx::resource_desc desc{};
	desc.as_texture_2d((u64)width, height, DXGI_FORMAT_R8G8B8A8_UNORM, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET);

	clear_value.Format = desc.Format;

	DXASSERT(device()->CreateCommittedResource(&d3dx::heap_properties.default_heap, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, &clear_value, IID_PPV_ARGS(this->GetAddressOf())));

	d3dx::view_desc vd{};

	device()->CreateShaderResourceView(ptr_, vd.as_srv_texture_2d(), this->shader_view.cpu);
	device()->CreateRenderTargetView(ptr_, nullptr, this->render_view.cpu);
}

D3D12_GPU_DESCRIPTOR_HANDLE primal::gfx::RenderTarget::get_id()
{
	return shader_view.gpu;
}

void primal::gfx::RenderTarget::begin(ID3D12GraphicsCommandListN* list)
{
	d3dx::resource_barrier barr{};
	barr.add(ptr_, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
	barr.apply(list);
	list->RSSetViewports(1u, &view_port);
	list->RSSetScissorRects(1u, &scissor);
	list->OMSetRenderTargets(1u, &render_view.cpu, FALSE, nullptr);
	//float color[4]{ 0.4f,0.5f,0.6f,1.0f };
	list->ClearRenderTargetView(render_view.cpu, clear_value.Color, 0u, nullptr);

}

void primal::gfx::RenderTarget::end(ID3D12GraphicsCommandListN * list)
{
	d3dx::resource_barrier barr{};
	barr.add(ptr_, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
	barr.apply(list);
}
